﻿using Entities;
using Entities.Admin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdminModels
{
    public enum ErrorType
    {
        Unknown = 0
        , Persistance = 1
        , Summary = 2
        , MarketGrab = 3
        , Pooling = 4
    }

    public static class ErrorLog
    {

        /// <summary>
        /// Persists an exception, saves a different ErrorLog if it fails
        /// </summary>
        /// <param name="ex">Exception to Persist</param>
        /// <param name="catchingMethod">Name of Method Catching Error, default "Unknown"</param>
        /// <param name="errorType">Error Type, default Unknown</param>
        /// <returns>If ErrorLog Persisted</returns>
        public static bool SaveLog(Exception ex, string catchingMethod = "Unknown",
            ErrorType errorType = ErrorType.Unknown)
        {
            bool sucess = false;

            try
            {
                using (AegirContext db = new AegirContext())
                {
                    ErrorLogEntity log = ParseErrorLog(ex, catchingMethod, errorType);
                    db.ErrorLog.Add(log);
                    db.SaveChanges();
                    sucess = true;
                }
            }
            catch (Exception ex2)
            {
                ErrorLogEntity log2 = ParseErrorLog(ex2, "ErrorLog", ErrorType.Persistance);
                SaveLog(log2);
            }

            return sucess;
        }

        /// <summary>
        /// Persists an ErrorLog,
        /// logs a different error if fails to log original
        /// </summary>
        /// <param name="log">ErrorLog To Persist</param>
        /// <returns>If ErrorLog Persisted</returns>
        private static bool SaveLog(ErrorLogEntity log)
        {
            bool sucess = false;

            try
            {
                using (AegirContext db = new AegirContext())
                {
                    db.ErrorLog.Add(log);
                    db.SaveChanges();
                    sucess = true;
                }
            }
            catch (Exception ex)
            {
                ErrorLogEntity log2 = ParseErrorLog(ex, "ErrorLog", ErrorType.Persistance);
                SaveLog(log2);
            }

            return sucess;
        }

        /// <summary>
        /// Creates an errorlog from an exception,
        /// Data Validation happens here, throws error if there is a problem
        /// </summary>
        /// <param name="ex">Exception to Parse</param>
        /// <param name="catchingMethod">Method Name that Caught the Exception, default "Unknown"</param>
        /// <param name="errorType">ErrorType, default Unknown</param>
        /// <returns></returns>
        private static ErrorLogEntity ParseErrorLog(Exception ex, string catchingMethod = "Unknown",
            ErrorType errorType = ErrorType.Unknown)
        {
            // TODO: Data Validation
            ErrorLogEntity log = new ErrorLogEntity();
            log.catchingmethod = catchingMethod;
            log.errortime = DateTime.Now;
            log.errortype = errorType.ToString();
            if (ex.InnerException != null)
            {
                log.innerexception = ex.InnerException.Message;
            }
            log.message = ex.Message;
            log.stacktrace = ex.StackTrace;

            return log;
        }
    }
}
